import { Meta2d, PenType, PrevNextType } from "@meta2d/core";
import type { Rect, Pen, Point } from '@meta2d/core';
import { parseSvg } from "@meta2d/svg";
import { ElMessage } from "element-plus";
import 'element-plus/theme-chalk/el-message.css';
import { reactive } from "vue";

export const menu = reactive({
  left: [
    {
      key: "file",
      name: "文件",
      icon: "l-folder",
      children: [
        {
          name: "新建文件",
          action: "newFile"
        },
        {
          name: "打开文件",
          action: "openFile"
        },
        {
          name: "导入文件",
          action: "loadFile"
        },
        {
          name: "导出JSON格式",
          action: "saveJson"
        },
        {
          name: "导出SVG格式",
          action: "saveSvg"
        },
        {
          name: "导出PNG格式",
          action: "savePng"
        }
      ]
    },
    {
      key: "edit",
      name: "编辑",
      icon: "l-gongyong--bianji",
      children: [
        {
          name: "添加/删除锚点(Shift+A)",
          action: "toggleAnchorMode"
        },
        {
          name: "添加手柄(Shift+H)",
          action: "addAnchorHand"
        },
        {
          name: "删除手柄(Shift+D)",
          action: "removeAnchorHand"
        },
        {
          name: "切换手柄类型(Shift)",
          action: "switchAnchorHandType"
        }
      ]
    },
    {
      key: "save",
      // name: "保存为",
      name: "保存",
      icon: "l-save",
      // children: [
      //   {
      //     name: "json",
      //     action: "saveJson"
      //   },
      //   {
      //     name: "svg",
      //     action: "saveSvg"
      //   },
      //   {
      //     name: "png",
      //     action: "savePng"
      //   }
      // ]
    }
  ],
  right: [
    {
      key: "undo",
      name: "撤销",
      icon: "l-cexiao",
      action: "undo",
      active: false
    },
    {
      key: "redo",
      name: "重做",
      icon: "l-chongzuo",
      action: "redo",
      active: false
    },
    {
      key: "magnifier",
      name: "放大镜",
      icon: "l-fangdajing",
      action: "openMagnifier",
      active: false
    },
    {
      key: "map",
      name: "鹰眼地图",
      icon: "l-ditu",
      action: "openMap",
      active: false
    },
    {
      key: "pen",
      name: "钢笔",
      icon: "l-curve",
      action: "usePen",
      active: false
    },
    {
      key: "pencil",
      name: "铅笔",
      icon: "l-qianbi",
      action: "usePencil",
      active: false
    },
    {
      key: "start",
      name: "起点",
      icon: "l-line",
      children: [
        {
          name: "",
          icon: "l-line",
          action: "start",
          value: "",
        },
        {
          name: "",
          icon: "l-from-triangle",
          action: "start",
          value: "triangle",
        },
        {
          name: "",
          icon: "l-from-diamond",
          action: "start",
          value: "diamond",
        },
        {
          name: "",
          icon: "l-from-circle",
          action: "start",
          value: "circle",
        },
        {
          name: "",
          icon: "l-from-lineDown",
          action: "start",
          value: "lineDown",
        },
        {
          name: "",
          icon: "l-from-lineUp",
          action: "start",
          value: "lineUp",
        },
        {
          name: "",
          icon: "l-from-triangleSolid",
          action: "start",
          value: "triangleSolid",
        },
        {
          name: "",
          icon: "l-from-diamondSolid",
          action: "start",
          value: "diamondSolid",
        },
        {
          name: "",
          icon: "l-from-circleSolid",
          action: "start",
          value: "circleSolid",
        },
        {
          name: "",
          icon: "l-from-line",
          action: "start",
          value: "line",
        },

      ]
    },
    {
      key: "end",
      name: "终点",
      icon: "l-line",
      children: [
        {
          name: "",
          icon: "l-line",
          action: "end",
          value: "",
        },
        {
          name: "",
          icon: "l-to-triangle",
          action: "end",
          value: "triangle",
        },
        {
          name: "",
          icon: "l-to-diamond",
          action: "end",
          value: "diamond",
        },
        {
          name: "",
          icon: "l-to-circle",
          action: "end",
          value: "circle",
        },
        {
          name: "",
          icon: "l-to-lineDown",
          action: "end",
          value: "lineDown",
        },
        {
          name: "",
          icon: "l-to-lineUp",
          action: "end",
          value: "lineUp",
        },
        {
          name: "",
          icon: "l-to-triangleSolid",
          action: "end",
          value: "triangleSolid",
        },
        {
          name: "",
          icon: "l-to-diamondSolid",
          action: "end",
          value: "diamondSolid",
        },
        {
          name: "",
          icon: "l-to-circleSolid",
          action: "end",
          value: "circleSolid",
        },
        {
          name: "",
          icon: "l-to-line",
          action: "end",
          value: "line",
        },
      ]
    },
    {
      key: "line",
      name: "连线",
      icon: "l-line",
      children: [{
        name: "",
        icon: "l-line",
        action: "line",
        value: "line"
      }, {
        name: "",
        icon: "l-curve2",
        action: "line",
        value: "curve"
      }, {
        name: "",
        icon: "l-polyline",
        action: "line",
        value: "polyline"
      }, {
        name: "",
        icon: "l-mind",
        action: "line",
        value: "mind"
      }]
    },
    {
      key: "manual",
      name: "手动锚点",
      icon: "l-maodian",
      action: "manual",
      active: false
    }
  ]
});

// 分发执行事件函数  
export function dispatchFunc(act : string | undefined, data : any) {
  if (!act) return false;
  menuFunc[act](data);
}

interface MenuFunc {
  [key : string] : (data : any) => void;
}

declare var showOpenFilePicker : Function;

const menuFunc : MenuFunc = {
  newFile() {
    meta2d.open();
  },
  // 打开文件
  async openFile() {
    const file = await showOpenFilePicker();
    if (!file) return false;
    const fileHandle = file[0];
    const dataObj = await fileHandle.getFile();
    const data = await dataObj.text();
    if (data && dataObj.type === 'application/json') {
      const json = JSON.parse(data);
      json.fileName = fileHandle.name.split(".").shift();
      meta2d.open(json);
      meta2d.emit('opened');
      meta2d.emit("changePens");
    } else {
      ElMessage({ message: '只能打开json文件', type: "error" });
    }
  },
  // 加载文件
  async loadFile() {
    const file = await showOpenFilePicker()
    if (!file) return false;
    const fileHandle = file[0];
    const dataObj = await fileHandle.getFile();
    const data = await dataObj.text();
    if (dataObj.type === 'image/svg+xml') {
      const pen = parseSvg(data)
      meta2d.canvas.addCaches = pen;
      ElMessage({ message: '添加成功，请点击放置点', type: "success" });
      return false
    }
    ElMessage({ message: '添加失败，暂且只支持svg文件', type: "error" });
  },
  // 放大镜
  openMagnifier(item) {
    if (meta2d.canvas.magnifierCanvas.magnifier) { // 判断放大镜状态  
      meta2d.hideMagnifier(); // 关闭放大镜  
    } else {
      meta2d.showMagnifier(); // 打开放大镜  
    }
    item.active = !item.active;
  },
  // 鹰眼
  openMap(item) {
    if (meta2d.map?.isShow) {
      meta2d.hideMap();  // 隐藏缩略图API
    } else {
      meta2d.showMap();  // 显示缩略图API
    }
    item.active = !item.active;
  },
  // 钢笔
  usePen(item) {
    if (meta2d.canvas.drawingLineName) {  // 判断是否正在使用钢笔
      meta2d.drawLine();   // 参数为空 取消钢笔
      meta2d.finishPencil(); // 绘画完成
      item.active = false;
    } else {
      meta2d.drawLine('curve');  // 使用钢笔 线条属性为curve
      item.active = true;
    }
  },
  // 铅笔
  usePencil(item) {
    if (meta2d.canvas.pencil) {
      meta2d.stopPencil();
      meta2d.finishPencil();
    } else {
      meta2d.drawingPencil();
    }
    item.active = !item.active;
  },
  // 保存json
  saveJson() {
    const jsonData = meta2d.data();
    const json = JSON.stringify(jsonData);  // 序列化json对象
    const file = new Blob([json], { type: "application/json" }); // 创建文件对象，指定类型为json
    const link = URL.createObjectURL(file); // 创建Url指向内存中的文件对象
    let a = document.createElement('a');  // 创建a标签用于下载操作
    a.setAttribute("download", (meta2d.store.options as any).fileName || '未命名');  // 设置download属性 第二个参数为文件名
    a.setAttribute("href", link);  // 设置a标签的数据来源
    a.click(); // 点击，开始下载
  },
  // 保存svg
  saveSvg() {
    downloadSvg();
  },
  // 保存png
  savePng() {
    let name = (meta2d.store.options as any).fileName;
    meta2d.downloadPng(name);
  },
  // 撤销
  undo() {
    meta2d.undo();
  },
  // 重做
  redo() {
    meta2d.redo();
  },
  // 终点
  end(item) {
    meta2d.store.data.toArrow = item.value;
    if (meta2d.store.active) {
      meta2d.store.active.forEach((i) => {
        if (i.type === PenType.Line) {
          i.toArrow = item.value;
        }
      })
    }
    meta2d.render();
  },
  // 起点
  start(item) {
    meta2d.store.data.fromArrow = item.value;

    if (meta2d.store.active) {
      meta2d.store.active.forEach((i) => {
        if (i.type === PenType.Line) {
          i.fromArrow = item.value;
        }
      })
    }
    meta2d.render();
  },
  // 连线
  line(item) {
    meta2d.store.options.drawingLineName = item.value;  // 修改全局连线样式配置
    meta2d.canvas.drawingLineName && (meta2d.canvas.drawingLineName = item.value);  // 修改当前连线样式
    meta2d.store.active?.forEach((pen) => {  // 修改已激活图元的连线样式
      meta2d.updateLineType(pen, item.value);  // meta2d的修改函数
    });
    meta2d.render();
  },
  // 锚点
  manual(item) {
    meta2d.toggleAnchorMode()
    item.active = !item.active;
  },
  // 添加/删除锚点
  toggleAnchorMode() {
    meta2d.toggleAnchorMode();
  },
  // 添加手柄
  addAnchorHand() {
    meta2d.addAnchorHand();
  },
  // 删除手柄
  removeAnchorHand() {
    meta2d.removeAnchorHand();
  },
  // 切换手柄类型
  switchAnchorHandType() {
    let activeAnchor : Point | undefined = meta2d.store.activeAnchor
    if (activeAnchor) {
      switch (activeAnchor.prevNextType) {
        case PrevNextType.Bilateral:
          activeAnchor.prevNextType = PrevNextType.Free
          break;
        case PrevNextType.Free:
          activeAnchor.prevNextType = PrevNextType.Mirror
          break;
        case PrevNextType.Mirror:
          activeAnchor.prevNextType = PrevNextType.Bilateral
          break;
        default:
          activeAnchor.prevNextType = PrevNextType.Bilateral
      }
      meta2d.render()
    }
  }

}

/** 下载svg fn */
function downloadSvg() {
  const rect : Rect = meta2d.getRect();
  rect.x = rect.x || 0;
  rect.y = rect.y || 0;
  rect.width = rect.width || 0;
  rect.height = rect.height || 0;
  rect.x -= 10;
  rect.y -= 10;
  const ctx = new C2S(rect.width + 20, rect.height + 20);
  ctx.textBaseline = 'middle';
  for (const pen of meta2d.store.data.pens) {
    if (pen.visible == false || !isShowChild(pen, meta2d.store)) {
      continue;
    }
    meta2d.renderPenRaw(ctx, pen, rect);
  }

  let mySerializedSVG = ctx.getSerializedSvg();
  if (meta2d.store.data.background) {
    mySerializedSVG = mySerializedSVG.replace('{{bk}}', '');
    mySerializedSVG = mySerializedSVG.replace(
      '{{bkRect}}',
      `<rect x="0" y="0" width="100%" height="100%" fill="${meta2d.store.data.background}"></rect>`
    );
  } else {
    mySerializedSVG = mySerializedSVG.replace('{{bk}}', '');
    mySerializedSVG = mySerializedSVG.replace('{{bkRect}}', '');
  }
  mySerializedSVG = mySerializedSVG.replace(/--le5le--/g, '&#x');
  const urlObject = window.URL || window;
  const export_blob = new Blob([mySerializedSVG]);
  const url = urlObject.createObjectURL(export_blob);
  const a = document.createElement('a');
  a.setAttribute(
    'download',
    `${(meta2d.store.options as any).fileName || '未命名'}.svg`
  );
  a.setAttribute('href', url);
  const evt = document.createEvent('MouseEvents');
  evt.initEvent('click', true, true);
  a.dispatchEvent(evt);
}

function isShowChild(pen : Pen, store : any) {
  let selfPen = pen;
  while (selfPen && selfPen.parentId) {
    const oldPen = selfPen;
    selfPen = store.pens[selfPen.parentId];
    const showChildIndex = selfPen?.calculative?.showChild;
    if (showChildIndex != undefined) {
      const showChildId = selfPen?.children ? selfPen?.children[showChildIndex] : undefined;
      if (showChildId !== oldPen.id) {
        return false;
      }
    }
  }
  return true;
}
